package com.hpq.chat.controller;



import com.hpq.chat.domain.dto.MsgReadInfoDTO;
import com.hpq.chat.domain.vo.request.*;
import com.hpq.chat.domain.vo.request.msg.ChatMessageBaseReq;
import com.hpq.chat.domain.vo.request.msg.ChatMessageMarkReq;
import com.hpq.chat.domain.vo.response.msg.ChatMessageReadResp;
import com.hpq.chat.domain.vo.response.msg.ChatMessageResp;
import com.hpq.chat.service.ChatService;
import com.hpq.common.annotation.FrequencyControl;
import com.hpq.common.domain.vo.response.ApiResult;
import com.hpq.common.domain.vo.response.CursorPageBaseResp;
import com.hpq.common.utils.RequestHolder;
import com.hpq.user.domain.enums.BlackTypeEnum;
import com.hpq.user.domain.model.Black;
import com.hpq.user.service.cache.UserCache;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 群成员表 前端控制器
 * </p>
 *
 * @author hpq
 * @since 2024-12-16
 */
@RestController
@RequestMapping("/capi/chat")
@Slf4j
@Api(tags = "聊天相关接口")
public class ChatController {
    @Autowired
    private ChatService chatService;
    @Autowired
    private UserCache userCache;

    @PostMapping("/msg")
    @ApiOperation("发送消息")
    @FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
    public ApiResult<ChatMessageResp> sendMsg(@Valid @RequestBody ChatMessageReq req){
        Long uid = RequestHolder.get().getUid();
        Long msgId =  chatService.sendMsg(req,uid);
        return ApiResult.success(chatService.getMsgResp(msgId,uid));
    }

    @GetMapping("/public/msg/page")
    @ApiOperation("获取消息列表")
    @FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
    public ApiResult<CursorPageBaseResp<ChatMessageResp>> getMsgResp(@Valid ChatMessagePageReq req){
        Long uid = RequestHolder.get().getUid();
        CursorPageBaseResp<ChatMessageResp> msgPage = chatService.getMsgPage(req,uid);
        filterBlackMsg(msgPage);
        return ApiResult.success(msgPage);
    }
    @PutMapping("/msg/recall")
    @ApiOperation("撤回消息")
    @FrequencyControl(time = 20, count = 3, target = FrequencyControl.Target.IP)
    public ApiResult<Void> recallMsg(@Valid @RequestBody ChatMessageBaseReq req){
        Long uid = RequestHolder.get().getUid();
        chatService.recallMsg(uid,req);
        return ApiResult.success();
    }
    @PutMapping("/msg/mark")
    @ApiOperation("消息标记")
    @FrequencyControl(time = 10, count = 5, target = FrequencyControl.Target.UID)
    public ApiResult<Void> setMsgMark(@Valid @RequestBody ChatMessageMarkReq request) {
        chatService.setMsgMark(RequestHolder.get().getUid(), request);
        return ApiResult.success();
    }
    @GetMapping("/msg/read/page")
    @ApiOperation("获取已读/未读消息列表")
    public ApiResult<CursorPageBaseResp<ChatMessageReadResp>> getReadMsgPage(@Valid ChatMessageReadReq req) {
        Long uid = RequestHolder.get().getUid();
        return ApiResult.success(chatService.getReadPage(req,uid));
    }
    @GetMapping("/msg/read")
    @ApiOperation("获取消息的已读未读总数")
    public ApiResult<Collection<MsgReadInfoDTO>> getReadInfo(@Valid ChatMessageReadInfoReq request) {
        Long uid = RequestHolder.get().getUid();
        return ApiResult.success(chatService.getMsgReadInfo(uid, request));
    }

    @PutMapping("/msg/read")
    @ApiOperation("消息阅读上报")
    public ApiResult<Void> msgRead(@Valid @RequestBody ChatMessageMemberReq request) {
        Long uid = RequestHolder.get().getUid();
        chatService.msgRead(uid, request);
        return ApiResult.success();
    }


    private void filterBlackMsg(CursorPageBaseResp<ChatMessageResp> msgPage) {
        Set<String> blackUidSet = getBlackUidSet();
        msgPage.getData().removeIf(a -> blackUidSet.contains(a.getFromUser().getUid().toString()));

    }
    private Set<String> getBlackUidSet() {
        return userCache.getBlackMap().getOrDefault(BlackTypeEnum.UID.getType(),new HashSet<>());
    }
}

